package vengadores;

import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

/**
 * Clase dedicada al manejo del héroe que será seleccionado.
 * @author Felipe Donato Arrazola Gómez
 * @author Jorge de Jesús Tinoco Huesca
 * @author Arturo Ayala Tello
 */
public class Heroe extends Sprite{
    /**
     * Atributo estática que representa las vidas que tendrá inicialmente el héroe
     */
    public static int VIDAS;
    /**
     * Atributo estática que representa la sangre que tendrá el héroe inicialmente.
     */
    public static int SANGRE;
    /**
     * Atributo estática que representará el último frame de la secuencia de Brincar.
     */
    public static int ULTBRINCO;
    /**
     * Atributo estática que representará el último frame de la secuencia para golpear.
     */
    public static int ULTGOLPE;
    /**
     * Atributo estática que representará el último frame de la secuencia donde el héroe es golpeado.
     */
    public static int ULTGOLPEADO;
    /**
     * Atributo estática que representará el último frame de la secuencia donde el héroe pierde toda la sangre.
     */
    public static int ULTMUERTO;
    /**
     * Atributo estática que representará el último frame de la secuencia donde el héroe brinca.
     */
    public static int MAX_BRINCO;
    /**
     * Es la velocidad con la que se moverá el héroe
     */
    protected static int VEL_DESP;
    /**
     * Atributo de tipo boolean que será si el héroe se está cubriendo en modo Shooter.
     */
    protected boolean estaCubierto = false;
    /**
     * Atributo de tipo boolean que será si el héroe está parpadeando.
     */
    protected boolean estaParpadeando = false;
    /**
     * Atributo de tipo boolean que será si el héroe está muriendo.
     */
    protected boolean estaMuriendo = false;
    /**
     * Atributo de tipo boolean que será si el héroe se está corriendo.
     */
    protected boolean estaCorriendo = false;
    /**
     * Atributo de tipo boolean que señala si el héroe está detenido.
     */
    protected boolean estaParado = false;
    /**
     * Atributo de tipo boolean que señala si el héreo está birncando
     */
    protected boolean estaBrincando = false;
    /**
     * Atributo de tipo boolean que señala si el héroe está golpeando.
     */
    protected boolean estaGolpeando = false;
    /**
     * Atributo de tipo boolean que señala si el héroe ha sido golpeado.
     */
    protected boolean haSidoGolpeado = false;
    /**
     * atributo que señala si el héroe está agachado-
     */
    protected boolean estaAgachado = false;
    /**
     * Atributo que señala si el héroe está cayendo
     */
    protected boolean estaCayendo = false;
    private int corriendo[]={1,1,2,2,3,3,4,4,5,5,6,6};//Secuencia para correr del Sprite del héroe
    private int posicionParado[] = {0};// secuencia para cuando el héroe esté detenido.
    private int brincoM[] = {11,11,12,12,13,13,14,14,15,15,16,16,17,17}; // secuencia para cuando la mujer esté brincando
    private int brincoH[] = {7,7,8,8,9,9,10,10,11,11,12,12,13,13}; // secuencia para cuando el hombre brinca
    private int golpeH[] = {18,19,20,21,22,22,23,23};// secuencia para cuando el hombre golpee
    private int golpeM[] = {23,23,24,24,25,25};//secuencia para cuando la mujer golpee
    private int golpeadoH[]= {24,24,25,25,26,26};//secuencia para cuando el hombre es golpeado
    private int golpeadoM[]= {26,26,27,27,28,28};// secuencia para cuando la mujer es golpeada
    private int agacharH[] = {17};//secuencia para cuando el hombre se agache
    private int agacharM[] = {21};//secuencia para cuando la mujer se agache
    private int cayendoH[] = {14};//secuencia para cuando el hombre esté cayendo
    private int cayendoM[] = {18};//secuencia para cuando la mujer esté cayendo
    private int muriendoH[] = {24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31,31,31,31,31,31};//secuencia para cuando el hombre se quede sin sangre
    private int muriendoM[] = {26,26,27,27,28,28,29,29,30,30,31,31,32,32};//secuencia para cuando la mujer se quede sin sangre
    private int sexo; // atributo que señalará que personaje ha sido seleccionado

    /**
     * Constructor de la clase donde se inicializan todos los atributos de los últimos frames así como la sangre y vida.
     * @param genero Género del personaje seleccionado, para escoger a Alma es 1 y para escoger a Larry es 0.
     * @throws IOException si no encuentra alguna imagen
     * @throws IllegalArgumentException si no puede ejecutarse algo dentro del constructor
     */
    public Heroe(int genero) throws IOException, IllegalArgumentException{
        super(Image.createImage("/SpriteVacio.png"));
        sexo = genero;
        VIDAS = 3;
        SANGRE = 6;
        if (sexo == 0){// 0=hombre
            super.setImage(Image.createImage("/SuperSpriteHombre.png"), 70, 76);
            ULTGOLPE = golpeH.length-1;
            ULTBRINCO = brincoH.length-1;
            ULTMUERTO = muriendoH.length-1;
            ULTGOLPEADO = golpeadoH.length-1;
            VEL_DESP = 4;
            MAX_BRINCO = 9;
        }else if(sexo == 1){ // 1 = mujer
            super.setImage(Image.createImage("/SuperSpriteMujer.png"), 62, 72);
            ULTGOLPE = golpeM.length-1;
            ULTBRINCO = brincoM.length-1;
            ULTMUERTO = muriendoM.length-1;
            ULTGOLPEADO = golpeadoM.length-1;
            VEL_DESP = 5;
            MAX_BRINCO = 11;
        }else
            throw new IllegalArgumentException();
    }

    /**
     * Método donde se pone la secuencia de correr para el héroe y dependiendo el parámetro es hacía dónde se mueve, si es true es hacia la derecha, en caso contrario hacia la izquierda
     * @param direccion boolean de hacía dónde se está moviendo el héroe
     */
    public void correr(boolean direccion){ //true = derecha, false = izquierda
        int x = getX();
        int y = getY();
        estaCayendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        haSidoGolpeado = false;
        if (!estaCorriendo){
            super.setFrameSequence(corriendo);
            estaCorriendo = true;
        }
        if(direccion){
            setTransform(Sprite.TRANS_NONE);
            setPosition(x,y);
            move(VEL_DESP,0);
        }else{
            setTransform(Sprite.TRANS_MIRROR);
            setPosition(x,y);
            move(-VEL_DESP,0);
        }
    }

    /**
     * Método que pone la secuencia donde está golpeando, manda a false todas las demás banderas.
     */
    public void golpear(){
        estaCayendo = false;
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaParado = false;
        haSidoGolpeado = false;
        if (!estaGolpeando){
            if (sexo == 0){
                super.setFrameSequence(golpeH);
            }else if (sexo == 1){
                super.setFrameSequence(golpeM);
            }
            estaGolpeando = true;
        }
        if (super.getFrame() == ULTGOLPE){
            estaGolpeando = false;
        }

    }

    /**
     * Método que pone la secuencia de que el héroe está detenido y manda a false las banderas diferentes a esta.
     */
    public void parado() {
        super.setFrameSequence(posicionParado);
        estaCayendo = false;
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        haSidoGolpeado = false;
        estaParado = true;
    }

    /**
     * Método que manda a false banderas que no sea la de la acción, y pone la secuencia de brincando
     */
    public void brincar(){
        estaCorriendo = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        estaCayendo = false;
        haSidoGolpeado = false;
        if(!estaBrincando){
            if(sexo == 0){
                super.setFrameSequence(brincoH);
            }else if(sexo == 1){
                super.setFrameSequence(brincoM);
            }
            estaBrincando = true;
        }
        move(0, -Heroe.MAX_BRINCO);
        if (super.getFrame() == ULTBRINCO){
            caer();
        }
    }

    /**
     * Método que manda a dibujar el Sprite del héroe
     * @param g entorno gráfico donde se puede dibujar.
     */
    public void dibujar(Graphics g){
        super.paint(g);
    }

    /**
     * Método que señala en true la bander de cayendo y false cualquier caso diferente y pone la secuencia de cayendo
     */
    public void caer() {
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        haSidoGolpeado = false;
        if (!estaCayendo){
            if (sexo == 0){
                super.setFrameSequence(cayendoH);
            }else if (sexo == 1){
                super.setFrameSequence(cayendoM);
            }
            estaCayendo = true;
        }
    }

    /**
     * Método similar a caer(), pero hace caer al héroe con la variable GRAVEDAD de la clase Juego
     */
    public void caerA() {
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        haSidoGolpeado = false;
        if (!estaCayendo){
            if (sexo == 0){
                super.setFrameSequence(cayendoH);
            }else if (sexo == 1){
                super.setFrameSequence(cayendoM);
            }
            estaCayendo = true;
        }
        super.move(0, Juego.GRAVEDAD);
    }

    /**
     * Método que pone la secuencia de modo Shooter.
     * @param cubierto boolean que pone si está cubierto el héroe.
     */
    public void posicionShooter(boolean cubierto){
        if(cubierto){
            if(sexo == 0){
                super.setFrame(32);
            }else if(sexo == 1){
                super.setFrame(34);
            }
            estaCubierto = true;
        }else{
            if(sexo == 0){
                super.setFrame(33);
            }else if(sexo == 1){
                super.setFrame(33);
            }
            estaCubierto = false;
        }
    }

    /**
     * Método que pone la secuencia de cuando el héroe está agachado
     */
     public void agachar() {
        estaCorriendo = false;
        estaBrincando = false;
        estaGolpeando = false;
        estaParado = false;
        estaCayendo = false;
        haSidoGolpeado = false;
        if (!estaAgachado){
             if (sexo == 0){
                super.setFrameSequence(agacharH);
            }else if (sexo == 1){
                super.setFrameSequence(agacharM);
            }
            estaAgachado = true;
        }

    }

     /**
      * Método que hace parpadear al héroe
      */
    public void parpadear(){
        int x = getX();
        int y = getY();
        estaParpadeando = !estaParpadeando;
        if(!estaParpadeando){
            super.setVisible(true);
            super.setPosition(x, y);
        }else{
            super.setVisible(false);
            super.setPosition(x, y);
        }
    }

    /**
     * Método que pone la secuencia de cuando el héroe esta muriendo
     */
    public void morir(){
        estaCayendo = false;
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        if(!estaMuriendo){
            if (sexo == 0){
                super.setFrameSequence(muriendoH);
            }else if (sexo == 1){
                super.setFrameSequence(muriendoM);
            }
            estaMuriendo = true;
        }
        if (super.getFrame() == ULTMUERTO){
            estaMuriendo = false;
        }
    }

    /**
     * Método que pone la secuencia del Sprite de cuando el héroe ha sido golpeado
     */
    public void golpeado() {
        estaCayendo = false;
        estaCorriendo = false;
        estaBrincando = false;
        estaAgachado = false;
        estaGolpeando = false;
        estaParado = false;
        estaMuriendo = false;
        if(!haSidoGolpeado){
            if (sexo == 0){
                super.setFrameSequence(golpeadoH);
            }else if (sexo == 1){
                super.setFrameSequence(golpeadoM);
            }
            haSidoGolpeado = true;
        }
        if (super.getFrame() == ULTGOLPEADO){
            haSidoGolpeado = false;
        }
    }

    /**
     * Método que cambia el atributo SANGRE
     * @param sangrePersonaje recibe un int con la nueva sangre
     */
    public void setSangre(int sangrePersonaje) {
        SANGRE = sangrePersonaje;
    }

    /**
     * Método que cambia el atributo VIDAS
     * @param vidasPersonaje int que será el nuevo número de vidas.
     */
    public void setVidas(int vidasPersonaje) {
        VIDAS = vidasPersonaje;
    }
}
